/**
 * Copyright (c) 2022 Presto Labs Pte. Ltd.
 * Author: Ju
 */

#pragma once

#include <atomic>
#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/spawn.hpp>
#include <cstdint>
#include <memory>

#include "coin2/exchange/base/order/control/network/tcp_connection.h"

namespace coin2::exchange::base::order {

using boost::asio::ip::tcp;

class TcpServer {
 public:
  // If you need to use server
  // you need to inherit the callback class and hold the conn
  class Callback {
   public:
    virtual ~Callback() = default;
    virtual void OnConnect(std::weak_ptr<TcpConnection> conn) = 0;
  };

  TcpServer(boost::asio::io_context* ioc, uint16_t port, Callback* callback);
  ~TcpServer();

  void RunAsync();

  void Close();

 private:
  boost::asio::io_context* ioc_;
  boost::asio::io_context::strand strand_;
  Callback* callback_;

  uint16_t port_;
  tcp::acceptor acceptor_;

  std::atomic<bool> running_;
};
}  // namespace coin2::exchange::base::order
